package com.mgy.example.service.common.lock;

import com.mgy.example.service.common.config.zk.CuratorConfig;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.concurrent.TimeUnit;

@Service
public class ZkLockService {
    @Autowired
    private CuratorConfig curatorConfig;
    @Autowired
    private CuratorFramework curatorFramework;

    /**
     * 创建分布式锁, 锁空间的根节点路径为/lockRoot
     */
    @PostConstruct
    public void init() {

    }

    /**
     * 尝试获取锁，没有获取到锁一直等待
     */
    public InterProcessMutex tryLock(String path) throws Exception {
        InterProcessMutex mutex = new InterProcessMutex(curatorFramework, curatorConfig.getLockRoot() + "/" + path);
        mutex.acquire();
        return mutex;
    }

    /**
     * 尝试获取锁，没有获取锁等待
     *
     * @param timeout 等待超时时间,单位秒
     */
    public InterProcessMutex tryLock(String path, long timeout) throws Exception {
        InterProcessMutex mutex = new InterProcessMutex(curatorFramework, curatorConfig.getLockRoot() + "/" + path);
        mutex.acquire(timeout, TimeUnit.MINUTES);
        return mutex;
    }

    /**
     * 尝试获取锁，没有获取到锁一直等待
     */
    public InterProcessMutex tryLock() throws Exception {
        InterProcessMutex mutex = new InterProcessMutex(curatorFramework, curatorConfig.getLockRoot());
        mutex.acquire();
        return mutex;
    }

    /**
     * 尝试获取锁，没有获取锁等待
     *
     * @param timeout 等待超时时间,单位秒
     */
    public InterProcessMutex tryLock(long timeout) throws Exception {
        InterProcessMutex mutex = new InterProcessMutex(curatorFramework, curatorConfig.getLockRoot());
        mutex.acquire(timeout, TimeUnit.MINUTES);
        return mutex;
    }

    /**
     * 释放锁
     */
    public void unLock(InterProcessMutex mutex) throws Exception {
        //释放锁
        mutex.release();
    }

    @PreDestroy
    public void close() {
        //关闭客户端
        if (curatorFramework != null) {
            curatorFramework.close();
        }
    }
}
